/*
 * Copyright (c)  2020,  DataPipeline
 * All rights reserved.
 *
 * Id:ObjectBuilderHolder.java   2020-07-18 16:21 wanglijun
 */
package cn.datacare.orm.annotation.builder;

import cn.datacare.orm.annotation.Builder;
import cn.datacare.orm.exception.OrmCoreException;
import cn.datacare.orm.exception.OrmErrorCode;
import cn.datacare.orm.util.BeanUtils;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 * Title:
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: Copyright (c) 2020
 * </p>
 * <p>
 * Company/Department: DataPipeline
 * </p>
 *
 * @author wanglijun
 * @version 1.0
 * @since 2020-07-18 16:21
 */
public class ObjectBuilderHolder {

    private static Map<Class, Object> classHandlerMap = new ConcurrentHashMap<>();

    private Annotation annotation;

    private Builder builder;

    private Object instance;

    /***
     *
     * @param annotation
     * @param builder
     */
    public ObjectBuilderHolder(Annotation annotation, Builder builder) {
        this.annotation = annotation;
        this.builder = builder;
        this.instance = newInstance(builder.value());
    }

    public Object newInstance(Class objectHandlerClz) {
        if (classHandlerMap.containsKey(objectHandlerClz)) {
            return classHandlerMap.get(objectHandlerClz);
        }

        Object objectHandler = BeanUtils.newInstance(objectHandlerClz);
        if (objectHandler instanceof ObjectPersistBuilder || objectHandler instanceof ObjectSelectBuilder) {
            classHandlerMap.put(objectHandlerClz, objectHandler);
            return objectHandler;
        } else {
            throw new OrmCoreException(OrmErrorCode.ANNOTATION_DEFINE_ERROR, objectHandlerClz.getSimpleName());
        }

    }


    public Annotation getAnnotation() {
        return annotation;
    }

    public void setAnnotation(Annotation annotation) {
        this.annotation = annotation;
    }

    public Builder getBuilder() {
        return builder;
    }

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

    public Object getInstance() {
        return instance;
    }

    public void setInstance(Object instance) {
        this.instance = instance;
    }
}
